home *** CD-ROM | disk | FTP | other *** search
- /*
- * Use SetScrollValue() in preference to SetCtlValue() when setting scroll
- */
-
- /*
- * TransDisplay version 3.05 - TransSkel plug-in module supporting
- * an arbitrary number of generic display windows with memory.
- *
- * TransSkel and TransDisplay are public domain. For more information,
- * contact:
- *
- * Paul DuBois
- * Wisconsin Regional Primate Research Center
- * 1220 Capitol Court
- * Madison, WI 53715-1299 USA
- *
- * Internet: dubois@primate.wisc.edu
- *
- *
- * This version of TransDisplay is written for THINK C 6.0.
- * THINK C is a trademark of:
- *
- * Symantec Corporation
- * 10201 Torre Avenue
- * Cupertino, CA 95014 USA
- *
- * History
- * 08/25/86 Genesis. Beta version.
- *
- * 09/15/86 Release 1.0
- * Changed to allow arbitrary number of windows.
- *
- * 01/17/87 Release 1.01
- * The window type when a new window is created with NewDWindow is
- * documentProc+8 now, so that the window will have a zoom box on a
- * machine with 128K ROMS.
- *
- * 01/29/89 Release 2.0
- * Converted to work with TransSkel 2.0. Display window creation routines
- * now check whether window and window handler creation succeeded and
- * return nil if not. 2-byte and 4-byte integer types are typedef'ed to
- * Integer and LongInt to ease porting.
- *
- * 24 Dec 90 Release 3.01
- * - Started converting to work with TransSkel 3.
- * - Began adding prototypes.
- * 01 Jan 91
- * - Took out the Macintosh header file #includes. <MacHeaders> is assumed
- * to be turned on so that it's not necessary.
- * 06 Jun 92
- * - Fixed GetDWindowTE() bug. Was returning nil under multiwindow
- * compilation.
- *
- * 05 Jun 93 Release 3.02
- * - Conversion for THINK C 6.0.
- *
- * 07 Jun 93 Release 3.03
- * - Took out all the stuff to allow compiling to handle only a single
- * display window. The savings in bytes of object code is no longer worth
- * the extra source code complexity. It's also unnecessary because I no longer
- * maintain a window list, since I ...
- * - Reimplemented linked list holding display window data using TransSkel's
- * window property functions (new in TS 3.00). The property type is
- * skelWPropDisplayWind, and the data value is a handle to the window data
- * structure.
- * - Took out all the "register" declarations. The compiler's smart enough
- * now that they don't make any difference, so they're just clutter.
- * 05 Jul 93
- * - Fixed Activate() and Update() so that when a window goes inactive,
- * the scroll bar is hidden (and only the frame drawn). Previously, the
- * scroll bar was just made inactive, which doesn't quite conform to the user
- * interface guidelines.
- * 17 Oct 93
- * - Added DisplayOSType() function.
- * 25 Nov 93
- * - Tests to check whether a window is the active window now test w->hilited
- * rather than FrontWindow(), since the front window of a suspended application
- * isn't active.
- * - Changed GetDWindow() so the WindowPtr is returned as the function value
- * rather than in the argument.
- * 21 Dec 93
- * - Use color grafports when available.
- * 04 Jan 94
- * - Undid Integer/LongInt type stuff back to short/long.
- *
- * 18 Jan 94 Release 3.04
- * - DisplayInt() and DisplayHexInt() are problematic since the THINK C can
- * treat int's as either 2 or 4 bytes. Added new routines DisplayShort()
- * and DisplayHexShort() which are unambiguous for 2 byte integers.
- * DisplayInt() and DisplayHexInt() are now deprecated and will disappear
- * in the future.
- * - New routine DisplayCString() for C-style strings.
- * 19 Jan 94
- * - Window creation routines do better checks for allocation failures.
- * - Much rewriting to eliminate many global variables. No more SyncGlobals().
- *
- * 20 Feb 94 Release 3.05
- * - Updated for TransSkel 3.11.
- * - Converted interface to be Pascal-compatible.
- */
-
-
- # include "TransSkel.h"
-
- # include "TransDisplay.h"
-
-
- # define normalHilite 0
- # define dimHilite 255
-
- # define WindowIsActive(w) ((WindowPeek) (w))->hilited
-
-
- /*
- * New(TypeName) returns handle to new object, for any TypeName.
- * If there is insufficient memory, the result is nil.
- */
-
- # define New(type) (type **) NewHandle ((Size) sizeof (type))
-
-
- /*
- * Default values for display window characteristics. Used when
- * new display windows are created.
- */
-
- static short d_font = monaco; /* default font */
- static short d_size = 9; /* default pointsize */
- static short d_wrap = 0; /* default word wrap (on) */
- static short d_just = teJustLeft; /* default justification */
- static long d_maxText = 30000L; /* default max text allowed */
- static long d_flushAmt = 25000L; /* default autoflush amount */
- static TDispActivateProcPtr d_activate = (TDispActivateProcPtr) nil; /* default notification proc */
-
-
- /*
- * Lowest allowable values for autoflush characteristics
- */
-
- # define d_loMaxText (100L)
- # define d_loFlushAmt (100L)
-
-
- /*
- * Display window document record. A handle to a window's document
- * record is stored in the window's property list.
- */
-
- typedef struct DocRecord DocRecord, *DocPtr, **DocHandle;
-
- struct DocRecord
- {
- WindowPtr dWind; /* display window */
- TEHandle dTE; /* window text */
- ControlHandle dScroll; /* window scroll bar */
- TDispActivateProcPtr dActivate; /* notification procedure */
- long dMaxText; /* max text length */
- long dFlushAmt; /* amount to autoflush */
- };
-
-
- /*
- * Macros for accessing parts of a document record, given a document
- * handle.
- */
-
- # define DocWind(doc) ((**doc).dWind)
- # define DocTE(doc) ((**doc).dTE)
- # define DocScroll(doc) ((**doc).dScroll)
- # define DocActivateProc(doc) ((**doc).dActivate)
- # define DocMaxText(doc) ((**doc).dMaxText)
- # define DocFlushAmt(doc) ((**doc).dFlushAmt)
-
-
- /*
- * curDispWind is the current output window.
- * If curDispWind = nil, output is currently turned off.
- */
-
- static WindowPtr curDispWind = nil;
-
-
-
- /* -------------------------------------------------------------------- */
- /* Miscellaneous Internal (private) Routines */
- /* -------------------------------------------------------------------- */
-
-
- /*
- * Draw grow box of dispWind in lower right hand corner
- */
-
-
- static void
- DrawGrowBox (WindowPtr w)
- {
- RgnHandle oldClip;
- Rect r;
-
- r = w->portRect;
- r.left = r.right - 15; /* draw only in corner */
- r.top = r.bottom - 15;
- oldClip = NewRgn ();
- GetClip (oldClip);
- ClipRect (&r);
- DrawGrowIcon (w);
- SetClip (oldClip);
- DisposeRgn (oldClip);
- }
-
-
-
- /* -------------------------------------------------------------------- */
- /* Lowest-level Internal (Private) Display Window Routines */
- /* -------------------------------------------------------------------- */
-
-
- /*
- * Get document handle associated with display window.
- * Return nil if window isn't a known display window.
- */
-
- static DocHandle
- WindDocHandle (WindowPtr w)
- {
- SkelWindPropHandle ph;
- DocHandle doc = (DocHandle) nil;
-
- if (w != (WindowPtr) nil)
- {
- ph = SkelGetWindProp (w, skelWPropDisplayWind);
- if (ph != (SkelWindPropHandle) nil)
- doc = (DocHandle) (**ph).skelWPropData;
- }
- return (doc);
- }
-
-
- /*
- * Calculate the dimensions of the editing rectangle for
- * a window (which is assumed to be
- * the current port). (The viewRect and destRect are the
- * same size.) Assumes the port, text font and text size are all
- * set properly. The viewRect is sized so that an integral
- * number of lines can be displayed in it, i.e., so that a
- * partial line never shows at the bottom.
- */
-
- static void
- CalcEditRect (WindowPtr w, Rect *r)
- {
- FontInfo f;
- short lineHeight;
-
- GetFontInfo (&f);
- lineHeight = f.ascent + f.descent + f.leading;
- *r = w->portRect;
- r->left += 4;
- r->right -= 17; /* leave room for scroll bar + 2 */
- r->top += 2;
- r->bottom = r->top + ((r->bottom - r->top - 2) / lineHeight) * lineHeight;
- }
-
-
- /*
- * Calculate the dimensions of the scroll bar rectangle for a
- * window. Make sure that the edges overlap the window frame and
- * the grow box.
- */
-
- static void
- CalcScrollRect (WindowPtr w, Rect *r)
- {
- *r = w->portRect;
- ++r->right;
- --r->top;
- r->left = r->right - 16;
- r->bottom -= 14;
- }
-
-
- /*
- * Calculate the number of lines currently scrolled off
- * the top of an edit record.
- */
-
- static short
- LinesOffTop (TEHandle hTE)
- {
- return (((**hTE).viewRect.top - (**hTE).destRect.top) / (**hTE).lineHeight);
- }
-
-
- /*
- * Highlight the scroll bar properly. This means that it's not
- * made active if the window itself isn't active, even if
- * there's enough text to fill the window.
- */
-
- static void
- HiliteScroll (DocHandle doc)
- {
- WindowPtr w;
- ControlHandle scroll;
- short hilite;
-
- w = DocWind (doc);
- scroll = DocScroll (doc);
- hilite = (WindowIsActive (w) && GetCtlMax (scroll) > 0
- ? normalHilite : dimHilite);
- HiliteControl (scroll, hilite);
- }
-
-
- /*
- * Set scroll bar current value (but only if it's different than
- * the current value, to avoid needless flashing).
- */
-
- static void
- SetScrollValue (ControlHandle scroll, short value)
- {
- if (GetCtlValue (scroll) != value)
- SetCtlValue (scroll, value);
- }
-
-
- /*
- * Scroll to the correct position. lDelta is the
- * amount to CHANGE the current scroll setting by.
- * Positive scrolls the text up, negative down.
- */
-
- static void
- ScrollText (DocHandle doc, short lDelta)
- {
- ControlHandle scroll;
- TEHandle hTE;
- short topVisLine;
- short newTopVisLine;
-
- scroll = DocScroll (doc);
- hTE = DocTE (doc);
-
- topVisLine = LinesOffTop (hTE);
- newTopVisLine = topVisLine + lDelta;
- if (newTopVisLine < 0) /* clip to range */
- newTopVisLine = 0;
- if (newTopVisLine > GetCtlMax (scroll))
- newTopVisLine = GetCtlMax (scroll);
- SetScrollValue (scroll, newTopVisLine);
- TEScroll (0, (topVisLine - newTopVisLine ) * (**hTE).lineHeight, hTE);
- }
-
-
- /*
- * Filter proc for tracking mousedown in scroll bar.
- *
- * Scroll by one line if the mouse is in an arrow. Scroll by a half
- * window's worth of lines if the mouse is in a page region.
- *
- * TrackScroll() uses scrollDoc and scrollPart, which must be set in
- * Mouse() before calling TrackControl(), which calls TrackScroll().
- * scrollPart is the original part code in which the mousedown occurred.
- */
-
- static DocHandle scrollDoc;
- static short scrollPart;
-
- static pascal void
- TrackScroll (ControlHandle theScroll, short partCode)
- {
- TEHandle hTE;
- short lDelta;
- short halfPage;
-
- hTE = DocTE (scrollDoc);
- if (partCode == scrollPart) /* still in same part? */
- {
- halfPage = (((**hTE).viewRect.bottom - (**hTE).viewRect.top)
- / (**hTE).lineHeight) / 2;
- if (halfPage == 0)
- ++halfPage;
- switch (partCode)
- {
- case inUpButton: lDelta = -1; break;
- case inDownButton: lDelta = 1; break;
- case inPageUp: lDelta = -halfPage; break;
- case inPageDown: lDelta = halfPage; break;
- }
- ScrollText (scrollDoc, lDelta);
- }
- }
-
-
- /*
- * Overhaul the entire display. This is called after catastrophic
- * events, such as resizing the window, or changes to the word
- * wrap style. It makes sure the view and destination rectangles
- * are sized properly, and that the bottom line of text never
- * scrolls up past the bottom line of the window (if there's
- * enough to fill the window), and that the scroll bar max and
- * current values are set properly.
- *
- * Resizing the dest rect just means resetting the right edge
- * (the top is NOT reset), since text might be scrolled off the
- * top (i.e., destRect.top != 0).
- */
-
- static void
- OverhaulDisplay (DocHandle doc)
- {
- WindowPtr w;
- TEHandle hTE;
- ControlHandle scroll;
- Rect r;
- short nLines; /* # of lines in TERec */
- short visLines; /* # of lines displayable in window */
- short topLines; /* # of lines currently scrolled off top */
- short scrollLines; /* # of lines to scroll down */
- short lHeight;
-
- w = DocWind (doc);
- hTE = DocTE (doc);
- scroll = DocScroll (doc);
- CalcEditRect (w, &r);
- (**hTE).destRect.right = r.right;
- (**hTE).viewRect = r;
- TECalText (hTE); /* recalc line starts */
- lHeight = (**hTE).lineHeight;
- nLines = (**hTE).nLines;
- visLines = (r.bottom - r.top) / lHeight;
- topLines = LinesOffTop (hTE);
-
- /*
- * If the text doesn't fill the window (visLines > nLines - topLines),
- * pull the text down if possible (if topLines > 0). Make sure not
- * to try to scroll down by more lines than are hidden off the top.
- */
- scrollLines = visLines - (nLines - topLines);
- if (scrollLines > 0 && topLines > 0)
- {
- if (scrollLines > topLines)
- scrollLines = topLines;
- TEScroll (0, scrollLines * lHeight, hTE);
- topLines -= scrollLines;
- }
- TEUpdate (&r, hTE);
-
- SetCtlMax (scroll, nLines - visLines < 0 ? 0 : nLines - visLines);
- SetCtlValue (scroll, topLines);
- HiliteScroll (doc);
- }
-
-
- /* ---------------------------------------------------------------- */
- /* Window Handler Routines */
- /* ---------------------------------------------------------------- */
-
-
- /*
- * Handle mouse clicks in window
- */
-
- static pascal void
- Mouse (Point thePt, long t, short mods)
- {
- WindowPtr w;
- DocHandle doc;
- ControlHandle scroll;
- short thePart;
- short oldCtlValue;
-
- GetPort (&w);
- doc = WindDocHandle (w);
- scroll = DocScroll (doc);
-
- if ((thePart = TestControl (scroll, thePt)) == inThumb)
- {
- oldCtlValue = GetCtlValue (scroll);
- if (TrackControl (scroll, thePt, nil) == inThumb)
- ScrollText (doc, GetCtlValue (scroll) - oldCtlValue);
- }
- else if (thePart != 0)
- {
- scrollDoc = doc; /* set globals for TrackScroll */
- scrollPart = thePart;
- (void) TrackControl (scroll, thePt, &TrackScroll);
- }
- }
-
-
- /*
- * Update window. The update event might be in response to a
- * window resizing. If so, move and resize the scroll bar,
- * and recalculate the text display.
- *
- * The ValidRect call is done because the HideControl adds the
- * control bounds box to the update region - which would generate
- * another update event! Since everything is redrawn below anyway,
- * the ValidRect is used to cancel the update.
- */
-
- static pascal void
- Update (Boolean resized)
- {
- WindowPtr w;
- DocHandle doc;
- ControlHandle scroll;
- TEHandle hTE;
- Rect r;
-
- GetPort (&w);
- doc = WindDocHandle (w);
- scroll = DocScroll (doc);
- hTE = DocTE (doc);
-
- if (resized)
- {
- r = w->portRect;
- EraseRect (&r);
- HideControl (scroll);
- r = (**scroll).contrlRect;
- ValidRect (&r);
- CalcScrollRect (w, &r);
- SizeControl (scroll, 16, r.bottom - r.top);
- MoveControl (scroll, r.left, r.top);
- OverhaulDisplay (doc);
- ShowControl (scroll);
- }
- else
- {
- r = (**hTE).viewRect;
- TEUpdate (&r, hTE); /* redraw text display */
- if (WindowIsActive (w))
- DrawControls (w); /* redraw scroll bar */
- else
- {
- /* draw outline of scroll, erase interior */
- r = (**scroll).contrlRect;
- FrameRect (&r);
- InsetRect (&r, 1, 1);
- EraseRect (&r);
- }
- }
-
- DrawGrowBox (w);
- }
-
-
- /*
- * When the window comes active, highlight the scroll bar appropriately.
- * When the window is deactivated, hide the scroll bar (this is drawn
- * immediately rather than invalidating the rectangle and waiting for
- * Update(), because that just seems too slow).
- *
- * Redraw the grow box.
- *
- * Notify the host as appropriate.
- *
- * Note that clicking close box hides the window, which generates a
- * deactivate event, so there is no need for a close notifier.
- */
-
- static pascal void
- Activate (Boolean active)
- {
- WindowPtr w;
- DocHandle doc;
- ControlHandle scroll;
- RgnHandle oldClip;
- Rect r;
-
- GetPort (&w);
- doc = WindDocHandle (w);
- scroll = DocScroll (doc);
-
- DrawGrowBox (w);
- if (active)
- {
- HiliteScroll (doc);
- ShowControl (scroll);
- }
- else
- {
- /* hide scroll but don't show it being hidden */
- oldClip = NewRgn ();
- GetClip (oldClip);
- SetRect (&r, 0, 0, 0, 0);
- ClipRect (&r);
- HideControl (scroll);
- SetClip (oldClip);
- DisposeRgn (oldClip);
- /* now erase inside of scroll (but not outline, to avoid flicker) */
- r = (**scroll).contrlRect; /* erase scroll */
- InsetRect (&r, 1, 1); /* but not outline */
- EraseRect (&r);
- }
-
- if (DocActivateProc (doc) != nil)
- (*DocActivateProc (doc)) (active);
- }
-
-
- /*
- * Clobber a display window. This routine is written defensively on the
- * assumption that not all pieces of a complete display window are present.
- * This allows it to be called by SkelRmveWind() during window creation
- * attempts if allocations fail.
- *
- * The window's skelWPropDisplayWind property structure will be disposed
- * of by TransSkel, but the data associated with it (returned by WindDocHandle())
- * must be disposed of here.
- *
- * If the window being clobbered is the current output window, do
- * SetDWindow (nil) to turn output off. Also set dispWind to nil in
- * case the window is the current display window.
- */
-
- static pascal void
- Clobber (void)
- {
- WindowPtr w;
- DocHandle doc;
- TEHandle hTE;
-
- GetPort (&w);
- doc = WindDocHandle (w);
-
- if (w == curDispWind)
- SetDWindow (nil);
-
- /*
- * Toss document record and any pieces that exist
- */
- if (doc != (DocHandle) nil)
- {
- if ((hTE = DocTE (doc)) != (TEHandle) nil)
- TEDispose (hTE); /* toss text record */
- DisposeHandle ((Handle) doc);
- }
- DisposeWindow (w); /* toss window (scroll bar, too) */
- }
-
-
- /* ---------------------------------------------------------------- */
- /* Control Routines */
- /* ---------------------------------------------------------------- */
-
-
- /*
- * Test whether a window is a legal display window or not
- */
-
- pascal Boolean
- IsDWindow (WindowPtr w)
- {
- return (WindDocHandle (w) != nil);
- }
-
-
- /*
- * Return handle to display window's text record
- */
-
- pascal TEHandle
- GetDWindowTE (WindowPtr w)
- {
- DocHandle doc;
-
- return ((doc = WindDocHandle (w)) == nil ? nil : DocTE (doc));
- }
-
-
- /*
- * Change the text display characteristics of a display window
- * and redisplay it. As a side effect, this always scrolls to the
- * home position.
- */
-
- pascal void
- SetDWindowStyle (WindowPtr w, short font, short size, short wrap, short just)
- {
- DocHandle doc;
- GrafPtr savePort;
- FontInfo f;
- TEHandle hTE;
- Rect r;
-
- if (w == nil) /* reset window creation defaults */
- {
- d_font = font;
- d_size = size;
- d_wrap = wrap;
- d_just = just;
- return;
- }
-
- if ((doc = WindDocHandle (w)) != (DocHandle) nil)
- {
- GetPort (&savePort);
- SetPort (w);
- hTE = DocTE (doc);
- r = (**hTE).viewRect;
- EraseRect (&r);
- r = (**hTE).destRect; /* scroll home without redrawing */
- OffsetRect (&r, 0, 2 - r.top);
- (**hTE).destRect = r;
-
- (**hTE).crOnly = wrap; /* set word wrap */
- TESetJust (just, hTE); /* set justification */
-
- TextFont (font); /* set the font and point size */
- TextSize (size); /* of text record (this is the */
- GetFontInfo (&f); /* hard part) */
- (**hTE).lineHeight = f.ascent + f.descent + f.leading;
- (**hTE).fontAscent = f.ascent;
- (**hTE).txFont = font;
- (**hTE).txSize = size;
-
- OverhaulDisplay (doc);
- SetPort (savePort);
- }
- }
-
-
- /*
- * Scroll the text in the window so that line lineNum is at the top.
- * First line is line zero.
- */
-
- pascal void
- SetDWindowPos (WindowPtr w, short lineNum)
- {
- GrafPtr savePort;
- DocHandle doc;
-
- if ((doc = WindDocHandle (w)) != (DocHandle) nil)
- {
- GetPort (&savePort);
- SetPort (w);
- ScrollText (doc, lineNum - GetCtlValue (DocScroll (doc)));
- SetPort (savePort);
- }
- }
-
-
- /*
- * Set display window activate notification procedure.
- * Pass nil to disable it.
- */
-
- pascal void
- SetDWindowNotify (WindowPtr w, TDispActivateProcPtr p)
- {
- DocHandle doc;
-
- if (w == nil) /* reset window creation default */
- d_activate = p;
- else if ((doc = WindDocHandle (w)) != (DocHandle) nil)
- DocActivateProc (doc) = p;
- }
-
-
- /*
- * Set display window autoflush characteristics
- */
-
- pascal void
- SetDWindowFlush (WindowPtr w, long maxText, long flushAmt)
- {
- DocHandle doc;
-
- if (maxText > 32767L)
- maxText = 32767L;
- if (maxText < d_loMaxText)
- maxText = d_loMaxText;
- if (flushAmt < d_loFlushAmt)
- flushAmt = d_loFlushAmt;
-
- if (w == nil) /* reset window creation defaults */
- {
- d_maxText = maxText;
- d_flushAmt = flushAmt;
- return;
- }
-
- if ((doc = WindDocHandle (w)) != (DocHandle) nil)
- {
- DocMaxText (doc) = maxText;
- DocFlushAmt (doc) = flushAmt;
- }
- }
-
-
- /*
- * Set which display window is to be used for output. If theWind
- * is nil, output is turned off. If theWind is not a legal display
- * window, nothing is done.
- */
-
- pascal void
- SetDWindow (WindowPtr w)
- {
- if (w == nil || IsDWindow (w))
- {
- curDispWind = w;
- }
- }
-
-
- /*
- * Get the WindowPtr of the current output display window. If
- * output is turned off, this will be nil.
- */
-
- pascal WindowPtr
- GetDWindow (void)
- {
- return (curDispWind);
- }
-
-
- /*
- * Flush text from the window and readjust the display.
- */
-
- pascal void
- FlushDWindow (WindowPtr w, long byteCount)
- {
- DocHandle doc;
- TEHandle hTE;
-
- if ((doc = WindDocHandle (w)) != (DocHandle) nil)
- {
- hTE = DocTE (doc);
- TESetSelect (0L, byteCount, hTE); /* select text */
- TEDelete (hTE); /* clobber it */
- OverhaulDisplay (doc);
- }
- }
-
-
- /*
- * Create and initialize a display window and the associated data
- * structures. If the window and data cannot be allocated, destroy
- * the window and return nil. Otherwise return the window.
- *
- * The window is made the current output window, but the caller should
- * set and restore the port before and after calling SetupDocWind().
- */
-
- static WindowPtr
- SetupDocWind (WindowPtr w)
- {
- Rect r;
- DocHandle doc;
- SkelWindPropHandle prop;
- ControlHandle scroll;
- TEHandle hTE;
-
- if (!SkelWindow (w, /* the window */
- Mouse, /* mouse click handler */
- nil, /* key clicks are ignored */
- Update, /* window updating procedure */
- Activate, /* window activate/deactivate procedure */
- nil, /* TransSkel hides window if no close proc */
- /* (generates deactivate event) */
- Clobber, /* window disposal procedure */
- nil, /* no idle proc */
- false)) /* irrelevant since no idle proc */
- {
- DisposeWindow (w);
- return (nil);
- }
-
- /*
- * After this point SkelRmveWind() can be called to remove the window
- * if any allocations fail.
- */
-
- /*
- * Get new document record, attach to window property list.
- * Also make document record point to window.
- */
-
- if (!SkelAddWindProp (w, skelWPropDisplayWind, (long) 0L))
- {
- SkelRmveWind (w);
- return (nil);
- }
- doc = New (DocRecord);
- if (doc == (DocHandle) nil)
- {
- SkelRmveWind (w);
- return (nil);
- }
- prop = SkelGetWindProp (w, skelWPropDisplayWind);
- (**prop).skelWPropData = (long) doc;
- DocWind (doc) = w;
-
- /*
- * Build the scroll bar. Make sure the borders overlap the
- * window frame and the frame of the grow box.
- */
-
- CalcScrollRect (w, &r);
- scroll = NewControl (w, &r, "\p", true, 0, 0, 0, scrollBarProc, 0L);
- DocScroll (doc) = scroll;
-
- /*
- * Create the TE record used for text display. Use defaults for
- * display characteristics. Setting window style overhauls
- * display, so can cancel any update event pending for the window.
- */
-
- CalcEditRect (w, &r);
- hTE = TENew (&r, &r);
- DocTE (doc) = hTE;
-
- if (scroll == (ControlHandle) nil || hTE == (TEHandle) nil)
- {
- SkelRmveWind (w);
- return (nil);
- }
-
- SetDWindowNotify (w, d_activate);
- SetDWindowFlush (w, d_maxText, d_flushAmt);
- SetDWindowStyle (w, d_font, d_size, d_wrap, d_just);
-
- /*
- * Make window current display output window
- */
-
- SetDWindow (w);
- return (w);
- }
-
-
- /*
- * Create and initialize a display window and the associated data
- * structures, and return the window pointer.
- *
- * The parameters are similar to those for NewWindow. See Inside
- * Macintosh.
- *
- * Preserves the current port. If the window is visible,
- * an activate event will follow, at which point the port
- * will be set to the window.
- */
-
- pascal WindowPtr
- NewDWindow (Rect *bounds, StringPtr title, Boolean visible,
- WindowPtr behind, Boolean goAway, long refCon)
- {
- WindowPtr w;
- GrafPtr savePort;
-
- if (SkelQuery (skelQHasColorQD))
- {
- w = NewCWindow (nil,
- bounds,
- title,
- visible,
- documentProc + 8,
- behind,
- goAway,
- refCon);
- }
- else
- {
- w = NewWindow (nil,
- bounds,
- title,
- visible,
- documentProc + 8,
- behind,
- goAway,
- refCon);
- }
-
- if (w != (WindowPtr) nil)
- {
- GetPort (&savePort);
- w = SetupDocWind (w); /* nil if allocation failed */
- SetPort (savePort);
- }
- return (w);
- }
-
-
- /*
- * Create and initialize a display window (using a resource) and
- * the associated data structures, and return the window pointer.
- * Install window in list of display windows. In single-window
- * mode, disallow creation of a new window if one already exists.
- *
- * The parameters are similar to those for GetNewWindow. See Inside
- * Macintosh.
- */
-
- pascal WindowPtr
- GetNewDWindow (short resourceNum, WindowPtr behind)
- {
- WindowPtr w;
- GrafPtr savePort;
-
- if (SkelQuery (skelQHasColorQD))
- w = GetNewCWindow (resourceNum, nil, behind);
- else
- w = GetNewWindow (resourceNum, nil, behind);
-
- if (w != (WindowPtr) nil)
- {
- GetPort (&savePort);
- w = SetupDocWind (w); /* nil if allocation failed */
- SetPort (savePort);
- }
- return (w);
- }
-
-
- /* ------------------------------------------------------------ */
- /* Output Routines */
- /* ------------------------------------------------------------ */
-
-
- /*
- * Write text to display area if output is on (curDispWind != nil).
- * DisplayText is the fundamental output routine. All other
- * output calls map (eventually) to it.
- *
- * First check whether the insertion will cause overflow and flush
- * out some stuff if so. Insert new text at the end, then test
- * whether lines must be scrolled to get the new stuff to show up.
- * If yes, then do the scroll. Set values of scroll bar properly
- * and highlight as appropriate.
- *
- * The current port is preserved. Since all output calls end up
- * here, it's the only output routine that has to save the port
- * and check whether output is on.
- */
-
- pascal void
- DisplayText (Ptr theText, long len)
- {
- DocHandle doc;
- TEHandle hTE;
- ControlHandle scroll;
- short nLines; /* # of lines in TERec */
- short dispLines; /* # of lines displayable in window */
- short topLines; /* # of lines currently scrolled off top */
- short scrollLines; /* # of lines to scroll up */
- short lHeight;
- Rect r;
- GrafPtr savePort;
-
- if (curDispWind == nil)
- return;
-
- GetPort (&savePort);
- SetPort (curDispWind);
- doc = WindDocHandle (curDispWind);
- hTE = DocTE (doc);
- scroll = DocScroll (doc);
-
- if ((**hTE).teLength + len > DocMaxText (doc)) /* check overflow */
- {
- FlushDWindow (curDispWind, DocFlushAmt (doc));
- DisplayString ((StringPtr) "\p\r(autoflush occurred)\r");
- }
-
- lHeight = (**hTE).lineHeight;
- TESetSelect (32767L, 32767L, hTE); /* set to insert at end */
- TEInsert (theText, len, hTE);
- r = (**hTE).viewRect;
- nLines = (**hTE).nLines;
- dispLines = (r.bottom - r.top) / lHeight;
- topLines = LinesOffTop (hTE);
- scrollLines = nLines - (topLines + dispLines);
- if (scrollLines > 0) /* must scroll up */
- TEScroll (0, -lHeight * scrollLines, hTE); /* scroll up */
- topLines = nLines - dispLines;
- if (topLines >= 0 && GetCtlMax (scroll) != topLines)
- {
- SetCtlMax (scroll, topLines);
- SetCtlValue (scroll, topLines);
- }
- HiliteScroll (doc);
- SetPort (savePort);
- }
-
-
- /*
- * Derived output routines:
- *
- * DisplayString Write (Pascal) string
- *
- * DisplayLong Write value of long integer
- * DisplayShort Write value of short integer
- * DisplayChar Write character
- *
- * DisplayHexLong Write value of long integer in hex (8 digits)
- * DisplayHexShort Write value of short integer in hex (4 digits)
- * DisplayHexChar Write value of character in hex (2 digit)
- *
- * DisplayOSType Write OSType value
- *
- * DisplayBoolean Write boolean value
- * DisplayLn Write carriage return
- */
-
- pascal void
- DisplayString (StringPtr str)
- {
- DisplayText ((Ptr) (str+1), (long) str[0]);
- }
-
-
- pascal void
- DisplayCString (char *str)
- {
- long len = 0;
- char *s;
-
- for (s = str; *s != '\0'; s++)
- ++len;
- DisplayText ((Ptr) str, len);
- }
-
-
- pascal void
- DisplayChar (short c)
- {
- char ch = c;
-
- DisplayText (&ch, 1L);
- }
-
-
- pascal void
- DisplayShort (short i)
- {
- DisplayLong ((long) i);
- }
-
-
- pascal void
- DisplayLong (long l)
- {
- Str255 s;
-
- NumToString (l, s);
- DisplayString (s);
- }
-
-
- pascal void
- DisplayLn (void)
- {
- DisplayChar ('\r');
- }
-
-
- pascal void
- DisplayBoolean (Boolean b)
- {
- DisplayString (b ? (StringPtr) "\ptrue" : (StringPtr) "\pfalse");
- }
-
-
- static char
- HexByte (short value) /* should be 0..15 */
- {
- DisplayChar ((char) (value + (value < 10 ? '0' : 'a' - 10)));
- }
-
-
- pascal void
- DisplayHexChar (short c)
- {
- HexByte ((short) (c >> 4) & 0x0f);
- HexByte ((short) c & 0x0f);
- }
-
-
- pascal void
- DisplayHexShort (short i)
- {
- DisplayHexChar ((char) ((i >> 8) & 0xff));
- DisplayHexChar ((char) (i & 0xff));
- }
-
-
- pascal void
- DisplayHexLong (long l)
- {
- DisplayHexShort ((short) (l >> 16) & 0xffff);
- DisplayHexShort ((short) l & 0xffff);
- }
-
-
- pascal void
- DisplayOSType (OSType type)
- {
- long l = (long) type;
-
- DisplayChar ((l >> 24) & 0xff);
- DisplayChar ((l >> 16) & 0xff);
- DisplayChar ((l >> 8) & 0xff);
- DisplayChar (l & 0xff);
- }
-